/****************************************************************************************
**  File: Color.hpp
**  Author: Asteroth
**  Date: 21/03/2009
****************************************************************************************/

#ifndef __COLOR_HPP__
#define __COLOR_HPP__

template <class T>
class Colorx
{
    private:
        static T min, max;
        T Null;

    public:
        T Red, Green, Blue, Alpha;

        /// --- Constructors ----------------------------------------------------
        Colorx();
        Colorx(const Colorx<T> &color);
        Colorx(T red, T green, T blue);
        Colorx(T red, T green, T blue, T alpha);

        /// --- Operators -------------------------------------------------------
        /// a = b
        inline Colorx<T> &operator = ( const Colorx<T> &set );
        /// a += b   a + b
        inline Colorx<T> &operator += ( const Colorx<T> &add );
        inline Colorx<T> operator + ( const Colorx<T> &add ) const;
        /// [0] -> Red, [1] -> Green, [2] -> Blue, [3] -> Alpha, [else] -> 0
        inline T &operator [] (int index);

};

template <class T> T Colorx<T>::min = 0.0;
template <class T> T Colorx<T>::max = sizeof(T)==1? 255: 1.0;

typedef Colorx<ubyte> Color;
typedef Colorx<float> Colorf;

const Color COLOR_BLACK             = Color(0, 0, 0, 255);
const Color COLOR_DARK_GRAY         = Color(63, 63, 63, 255);
const Color COLOR_GRAY              = Color(127, 127, 127, 255);
const Color COLOR_LIGHT_GRAY        = Color(191, 191, 191, 255);
const Color COLOR_WHITE             = Color(255, 255, 255, 255);

const Color COLOR_DARK_RED          = Color(127, 0, 0, 255);
const Color COLOR_DARK_GREEN        = Color(0, 127, 0, 255);
const Color COLOR_DARK_BLUE         = Color(0, 0, 127, 255);
const Color COLOR_DARK_YELLOW       = Color(127, 127, 0, 255);
const Color COLOR_DARK_VIOLET       = Color(127, 0, 127, 255);
const Color COLOR_DARK_CYAN         = Color(0, 127, 127, 255);

const Color COLOR_RED               = Color(255, 0, 0, 255);
const Color COLOR_GREEN             = Color(0, 255, 0, 255);
const Color COLOR_BLUE              = Color(0, 0, 255, 255);
const Color COLOR_YELLOW            = Color(255, 255, 0, 255);
const Color COLOR_VIOLET            = Color(255, 0, 255, 255);
const Color COLOR_CYAN              = Color(0, 255, 255, 255);

const Color COLOR_LIGHT_RED         = Color(255, 127, 127, 255);
const Color COLOR_LIGHT_GREEN       = Color(127, 255, 127, 255);
const Color COLOR_LIGHT_BLUE        = Color(127, 127, 255, 255);
const Color COLOR_LIGHT_YELLOW      = Color(255, 255, 127, 255);
const Color COLOR_LIGHT_VIOLET      = Color(255, 127, 255, 255);
const Color COLOR_LIGHT_CYAN        = Color(127, 255, 255, 255);

template <class T> Colorx<T>::Colorx()
    { Red = 0; Green = 0; Blue = 0; Alpha = 0; Null = 0; }
template <class T> Colorx<T>::Colorx(const Colorx<T> &color)
    { Red = color.Red; Green = color.Green; Blue = color.Blue; Alpha = color.Alpha; Null = 0; }
template <class T> Colorx<T>::Colorx(T red, T green, T blue)
    { Red = red; Green = green; Blue = blue; Alpha = max; Null = 0; }
template <class T> Colorx<T>::Colorx(T red, T green, T blue, T alpha)
    { Red = red; Green = green; Blue = blue; Alpha = alpha; Null = 0; }

template <class T> inline Colorx<T> &Colorx<T>::operator = (const Colorx<T> &set)
    { Red = set.Red; Green = set.Green; Blue = set.Blue; Alpha = set.Alpha; return *this; }
template <class T> inline Colorx<T> &Colorx<T>::operator += (const Colorx<T> &add)
    { Red = eMin(Red+add.Red, max); Green = eMin(Green+add.Green, max); Blue = eMin(Blue+Blue.Red, max); Alpha = eMin(Alpha+add.Alpha, max); return *this; }
template <class T> inline Colorx<T> Colorx<T>::operator + (const Colorx<T> &add) const
    { return Colorx<T>(eMin(Red+add.Red, max), eMin(Green+add.Green, max), eMin(Blue+Blue.Red, max), eMin(Alpha+add.Alpha, max)); }
template <class T> inline T &Colorx<T>::operator [] (int index)
    { if (index==0) return Red;
    else if (index==1) return Green;
    else if (index==2) return Blue;
    else if (index==3) return Alpha; return Null; }

#endif
